import json
import traceback
import re
from uuid import uuid4
from pydantic import BaseModel

from fastapi import APIRouter, Request, Form
from redis.exceptions import ConnectionError

from database import redis_cli, get_redis_client
from api_json_response import *

router = APIRouter(prefix='/collector')


class OkHttp(BaseModel):
    pin: str = ""
    headers: dict = None
    cookies: dict = None
    query: dict = None
    content: dict = None


class JdApp(BaseModel):
    pin: str = ""
    headers: dict = None
    cookies: dict = None


def cookies_str_to_cookies(s: str):
    results = {}
    for j in s.split(';'):
        results[j.split('=', 1)[0]] = j.split('=', 1)[-1]
    return results


def get_ok_http(ck_string):
    uuid = uuid4().hex.lower()[:16]
    cookies = cookies_str_to_cookies(ck_string)
    unionwsws = json.loads(cookies['unionwsws'])

    return {
        'pin': cookies['pin'],
        'headers': {
            'charset': 'UTF-8',
            'accept-encoding': 'br,gzip,deflate',
            'cache-control': 'no-cache',
            'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'content-length': '12',
            'user-agent': 'okhttp/3.12.1'
        },
        'cookies': cookies,
        'query': {
            "functionId": "serverConfig",
            "clientVersion": "9.4.0",
            "build": "86737",
            "client": "android",
            "d_brand": "OPPO",
            "d_model": "PBAM00",
            "osVersion": "8.1.0",
            "screen": "1424*720",
            "partner": "oppo",
            "oaid": "",
            "eid": unionwsws['devicefinger'],
            "sdkVersion": "27",
            "lang": "zh_CN",
            "uuid": uuid,
            "aid": uuid,
            # "area": "19_1607_3155_62119",
            "networkType": "wifi",
            "wifiBssid": "unknown",
        }
    }


@router.post('/ok_http')
async def ok_http(request: Request, ok_http: OkHttp):
    redis_key = f"info_{ok_http.pin}"
    while 1:
        try:
            redis_cli.hset(redis_key, mapping={'ok_http': json.dumps(ok_http.__dict__)})
        except ConnectionError:
            continue
        else:
            break
    return success
    # redis_cli.set("ok_http", "abc")


@router.post('/jd_app')
async def jd_app(request: Request, jd_app: JdApp):
    redis_key = f"info_{jd_app.pin}"
    while 1:
        try:
            redis_cli.hset(redis_key, mapping={'jd_app': json.dumps(jd_app.__dict__)})
        except ConnectionError:
            continue
        else:
            break
    return success


@router.post('/cookies')
async def cookies(request: Request, cookies: str = Form(...)):
    ok_http = get_ok_http(cookies)
    redis_key = f"info_{ok_http['pin']}"
    while 1:
        try:
            redis_cli.hset(redis_key, mapping={'ok_http': json.dumps(ok_http)})
        except ConnectionError:
            continue
        else:
            break
    return success


@router.post('/curl')
async def curl(request: Request, curl: str = Form(...)):
    if not curl.startswith('curl'):
        return fail

    try:
        ck_string = re.search("Cookie: (.*?)'.*-H", curl, re.I).group(1)
    except:
        fail['msg'] = f'{traceback.format_exc()}'
        return fail

    ok_http = get_ok_http(ck_string)

    redis_key = f"info_{ok_http['pin']}"
    while 1:
        try:
            redis_cli.hset(redis_key, mapping={'ok_http': json.dumps(ok_http)})
        except ConnectionError:
            continue
        else:
            break
    return success
